home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / shutdown.lzh / shutdown_5.1 / src / unmount.c < prev   
C/C++ Source or Header  |  1996-10-10  |  5KB  |  206 lines

  1. /*
  2.    unmount.c --- unmount filesystems.
  3.  
  4.    (c) Copyright 1995 SHW Wabnitz
  5.    Written by Bernhard Fastenrath (fasten@shw.com)
  6.  
  7.    This file may be distributed under the terms
  8.    of the GNU General Public License.
  9. */
  10.  
  11. #include "shutdown_cmd.h"
  12.  
  13. typedef struct {
  14.   struct Message   sp_Msg;
  15.   struct DosPacket sp_Pkt;
  16.   struct Node     *sp_Dev;
  17. } MyStandardPacket;
  18.  
  19. static void
  20. FreeList (List *list)
  21. {
  22.   Node *node, *next;
  23.  
  24.   for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
  25.   {
  26.     if (node -> ln_Name)
  27.       FreeMem (node -> ln_Name, node -> ln_Pri);
  28.     FreeMem (node, sizeof (Node));
  29.   }
  30. }
  31.  
  32. static void
  33. FreeStdPktList (List *list)
  34. {
  35.   Node *node, *next;
  36.  
  37.   for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
  38.     FreeMem (node, sizeof (MyStandardPacket));
  39. }
  40.  
  41. static int
  42. SendStandardPacket (MsgPort *mp, MyStandardPacket *sp, char *handler, ULONG action, ULONG arg1)
  43. {
  44.   DevProc *dp = NULL;
  45.  
  46.   dp = GetDeviceProc (handler, dp);
  47.   if (dp)
  48.   {
  49.     sp -> sp_Pkt.dp_Type = action;
  50.     sp -> sp_Pkt.dp_Arg1 = arg1;
  51.     SendPkt (&sp -> sp_Pkt, dp -> dvp_Port, mp);
  52.     FreeDeviceProc (dp);
  53.     return 1;
  54.   }
  55.   return 0;
  56. }
  57.  
  58. static int
  59. AllocateStandardPackets (List *pktlist, int count)
  60. {
  61.   MyStandardPacket *sp;  
  62.   int t;
  63.  
  64.   NewList (pktlist);
  65.  
  66.   for (t=0; t<count; t++)
  67.   {
  68.     if (!(sp = AllocMem (sizeof (MyStandardPacket), MEMF_PUBLIC | MEMF_CLEAR)))
  69.       break;
  70.     sp -> sp_Msg.mn_Length = sizeof (MyStandardPacket);
  71.     sp -> sp_Msg.mn_Node.ln_Name = (char *) &sp -> sp_Pkt;
  72.     sp -> sp_Pkt.dp_Link = &sp -> sp_Msg;
  73.     AddTail (pktlist, &sp -> sp_Msg.mn_Node);
  74.   }
  75.   return t;
  76. }
  77.  
  78. static int
  79. SendToAll (MsgPort *mp, ULONG action, ULONG arg1)
  80. {
  81.   int len, count = 0, icount = 0, out_of_mem = 0;
  82.   List devlist, pktlist;
  83.   MyStandardPacket *sp;
  84.   Node *node;
  85.   DosList *dl;
  86.   char *name;
  87.  
  88.   NewList (&devlist);
  89.   NewList (&pktlist);
  90.  
  91.   dl = LockDosList ( LDF_DEVICES | LDF_READ );
  92.  
  93.   while (dl = NextDosEntry (dl, LDF_DEVICES))
  94.   {
  95.     if (node = (Node *) AllocMem (sizeof (Node), MEMF_CLEAR))
  96.     {
  97.       name = BADDR (dl -> dol_Name);
  98.       len = (int) name[0];
  99.  
  100.       if (node -> ln_Name = AllocMem (len + 2, 0))
  101.       {
  102.         CopyMem (name+1, node -> ln_Name, len);
  103.         node -> ln_Name[len] = ':';
  104.         node -> ln_Name[len+1] = '\0';
  105.         node -> ln_Pri = len + 2;
  106.         AddTail (&devlist, node);
  107.         count ++;
  108.       }
  109.       else
  110.       {
  111.         out_of_mem = 1;
  112.         FreeMem (node, sizeof (Node));
  113.         break;
  114.       }
  115.     }
  116.   }
  117.  
  118.   UnLockDosList ( LDF_DEVICES | LDF_READ );
  119.  
  120.   if ((icount = AllocateStandardPackets (&pktlist, count)) == 0)
  121.     out_of_mem = 1;
  122.   count = icount;
  123.  
  124.   if (out_of_mem)
  125.   {
  126.     FreeList (&devlist);
  127.     return 0;
  128.   }
  129.  
  130.   node = devlist.lh_Head;
  131.   for (;;)
  132.   {
  133.     while (node -> ln_Succ)
  134.     {
  135.       if (sp = (MyStandardPacket *) RemHead (&pktlist))
  136.       {
  137.         sp -> sp_Dev = node;
  138.         SendStandardPacket (mp, sp, node -> ln_Name, ACTION_IS_FILESYSTEM, 0);
  139.         icount --;
  140.         node = node -> ln_Succ;
  141.       }
  142.     }
  143.     WaitPort (mp);
  144.  
  145.     while (sp = (MyStandardPacket *) GetMsg (mp))
  146.     {
  147.       icount ++;
  148.  
  149.       if (sp -> sp_Pkt.dp_Type == ACTION_IS_FILESYSTEM &&
  150.           sp -> sp_Pkt.dp_Res1 == DOSTRUE)
  151.       {
  152.         SendStandardPacket (mp, sp, sp -> sp_Dev -> ln_Name, action, arg1);
  153.         icount --;
  154.       }
  155.       else
  156.         AddTail (&pktlist, &sp -> sp_Msg.mn_Node);
  157.     }
  158.     if (!node -> ln_Succ && icount == count)
  159.       break;
  160.   }
  161.   FreeStdPktList (&pktlist);
  162.   FreeList (&devlist);
  163.   return 1;
  164. }
  165.  
  166. static int
  167. FsAction (MsgPort *mp, char *filesystem, ULONG action, ULONG arg)
  168. {
  169. #if 0
  170.   if (filesystem)
  171.     return !SendToHandler (mp, action, filesystem, arg);
  172.   else
  173. #endif
  174.   return !SendToAll (mp, action, arg);
  175. }
  176.  
  177. /*** public functions ***/
  178.  
  179. int
  180. Unmount (char *filesystem, int mode)
  181. {
  182.   MsgPort *mp;
  183.   int status;
  184.  
  185.   if (!(mp = CreatePort (NULL, 0)))
  186.     return 0;
  187.  
  188.   switch (mode)
  189.   {
  190.     case UMNT_INHIBIT:
  191.       status  = FsAction (mp, filesystem, ACTION_INHIBIT, DOSTRUE);
  192.       break;
  193.     case UMNT_READONLY:
  194.       status  = FsAction (mp, filesystem, ACTION_FLUSH, DOSTRUE);
  195.       status |= FsAction (mp, filesystem, ACTION_WRITE_PROTECT, DOSTRUE);
  196.       break;
  197.     case UMNT_REMOUNT:
  198.       /* status  = FsAction (mp, filesystem, ACTION_WRITE_PROTECT, DOSFALSE); */
  199.       status  = FsAction (mp, filesystem, ACTION_INHIBIT, DOSTRUE);
  200.       status |= FsAction (mp, filesystem, ACTION_INHIBIT, DOSFALSE);
  201.       break;
  202.   }
  203.   DeletePort (mp);
  204.   return !status;
  205. }
  206.